home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / fmplay11 / rol2scr.c < prev    next >
C/C++ Source or Header  |  1993-07-26  |  7KB  |  264 lines

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include"adlib.h"
  5.    
  6. /* Noooo.  Don't look at this code, turn back before it's too late! */
  7.    
  8. void FMLoadInstrument(char *insName,char *bankFile,FMInstrument *ins);
  9.  
  10. char insTable[255][9]; /* arrays are the best data structure conceivable */
  11.  
  12. /* This is the .scr file format.  Good luck.
  13.  
  14.    char percussive mode
  15.    char nm instruments
  16.    instrument data, 28 bytes per.
  17.    
  18.    0, char voice, char pitch, unsigned duration    ; play note
  19.    ; duration is in ticks, and pitch is one of those 11-123 numbers
  20.    1, char voice, char new volume
  21.    2, char voice, char new voice data
  22.    3, int # ticks to pause
  23.    4, end of song
  24.    */
  25.  
  26. #define NMVOICES 11
  27.  
  28. void flushWait(int waitTime,FILE *ofile)
  29. {BYTE b;
  30.  int i;
  31.  if (!waitTime)
  32.     return;
  33.  b=3;
  34.  fwrite(&b,sizeof(BYTE),1,ofile);
  35.  i=waitTime;
  36.  fwrite(&i,sizeof(i),1,ofile);
  37. }
  38.  
  39. void translateROL(char *rolName,char *outputName,char *bankFile)
  40. {FILE *rfile,*ofile;
  41.  BYTE b,perc;
  42.  long rolSize;
  43.  int j,i,v,tick,done,wait;
  44.  BYTE nmInstruments;
  45.  BYTE *rol,*tempoEvent,*noteEvent[NMVOICES],*p,
  46.  *insEvent[NMVOICES],*volumeEvent[NMVOICES],*pitchEvent[NMVOICES];
  47.  int nmTempo,nmTicks[NMVOICES],nmIns[NMVOICES],nmVolume[NMVOICES],
  48.  ticksLeft[NMVOICES],nmPitch[NMVOICES];
  49.  
  50.  rfile=fopen(rolName,"rb");
  51.  if (!rfile)
  52.     {printf("Can't open .rol file.\n");
  53.      exit(-1);
  54.     }
  55.  fseek(rfile,0,SEEK_END);
  56.  rolSize=ftell(rfile);
  57.  fseek(rfile,0,SEEK_SET);
  58.  rol=(BYTE *)malloc(sizeof(BYTE)*rolSize);
  59.  if (!rol)
  60.     {printf("Not enough memory. (or .rol file too big)\n");
  61.      exit(-1);
  62.     }
  63.  if (fread(rol,sizeof(BYTE),rolSize,rfile)!=rolSize)
  64.     {printf("Error reading .rol\n");
  65.      exit(-1);
  66.     }
  67.  fclose(rfile);
  68.  ofile=fopen(outputName,"wb");
  69.  if (!ofile)
  70.     {printf("Can't open output file.\n");
  71.      exit(-1);
  72.     }
  73.  b=rol[53];
  74.  if (b)
  75.     b=0;
  76.  else
  77.     b=1;
  78.  fwrite(&b,sizeof(b),1,ofile); /* read and write percussive flag */
  79.  perc=b;
  80.  /* seek to tempo events */
  81.  p=&(rol[201]);
  82.  nmTempo=*((int *)p);
  83.  tempoEvent=p+2;
  84.  p+=2+nmTempo*6;
  85.  for (v=0;v<NMVOICES;v++)
  86.     {p+=15;
  87.      nmTicks[v]=*((int *)p);
  88.      i=0;
  89.      p+=2;
  90.      noteEvent[v]=p;
  91.      while (i<nmTicks[v])
  92.     {i+=*((int *)(p+2));
  93.      p+=4;
  94.     }
  95.      p+=15;
  96.      nmIns[v]=*((int *)p);
  97.      p+=2;
  98.      insEvent[v]=p;
  99.      p+=nmIns[v]*14;
  100.      p+=15;
  101.      nmVolume[v]=*((int *)p);
  102.      p+=2;
  103.      volumeEvent[v]=p;
  104.      p+=nmVolume[v]*6;
  105.      p+=15;
  106.      nmPitch[v]=*((int *)p);
  107.      p+=2;
  108.      pitchEvent[v]=p;
  109.      p+=nmPitch[v]*6;
  110.     }
  111.  for (i=0;i<255;i++)
  112.     strcpy(insTable[i],"");
  113.  nmInstruments=0;
  114.  for (v=0;v<NMVOICES;v++)
  115.     {for (i=0;i<nmIns[v];i++)
  116.     {char *insName;
  117.      insName=(char *)(insEvent[v]+2+i*14);
  118.      for (j=0;j<nmInstruments;j++)
  119.         {if (!stricmp(insName,insTable[j]))
  120.         break;
  121.         }
  122.      if (j==nmInstruments)
  123.         strcpy(insTable[nmInstruments++],insName);
  124.     }
  125.     }
  126.  fwrite(&nmInstruments,sizeof(nmInstruments),1,ofile);
  127.  {FMInstrument ins;
  128.   for (i=0;i<nmInstruments;i++)
  129.      {FMLoadInstrument(insTable[i],bankFile,&ins);
  130.       fwrite(&ins,sizeof(ins),1,ofile);
  131.      }
  132.  }
  133.  tick=0;
  134.  for (i=0;i<NMVOICES;i++)
  135.     ticksLeft[i]=0;
  136.  done=0;
  137.  wait=0;
  138.  while (!done)
  139.     {done=1;
  140.      for (i=0;i<(perc?NMVOICES:9);i++)
  141.     {/* for every voice */
  142.      if (nmIns[i]>0)
  143.         {if (*((int *)(insEvent[i]))==tick)
  144.         {char *name;
  145.          flushWait(wait,ofile);
  146.          wait=0;
  147.          name=insEvent[i]+2;
  148.          for (j=0;j<nmInstruments;j++)
  149.             {if (!stricmp(name,insTable[j]))
  150.             break;
  151.             }
  152.          if (j==nmInstruments)
  153.             {printf("Arrggghh!\n");
  154.              exit(-1);
  155.             }
  156.          b=2;
  157.          fwrite(&b,sizeof(BYTE),1,ofile);
  158.          b=i;
  159.          fwrite(&b,sizeof(BYTE),1,ofile);
  160.          b=j;
  161.          fwrite(&b,sizeof(BYTE),1,ofile);
  162.          nmIns[i]--;
  163.          insEvent[i]+=14;
  164.         }
  165.         }
  166.      if (tick<nmTicks[i])
  167.         {done=0;
  168.          if (--ticksLeft[i]<=0)
  169.         {int num,duration;
  170.          num=*((int *)(noteEvent[i]));
  171.          duration=*((int *)(noteEvent[i]+2));
  172.          noteEvent[i]+=4;
  173.          ticksLeft[i]=duration;
  174.          if (num!=0)
  175.             {BYTE b;
  176.              flushWait(wait,ofile);
  177.              wait=0;
  178.              b=0;
  179.              fwrite(&b,sizeof(BYTE),1,ofile);
  180.              b=i;
  181.              fwrite(&b,sizeof(BYTE),1,ofile);
  182.              b=num;
  183.              fwrite(&b,sizeof(BYTE),1,ofile);
  184.              fwrite(&duration,sizeof(duration),1,ofile);
  185.             }
  186.         }
  187.         }
  188.     }
  189.      wait++;
  190.      tick++;
  191.     }
  192.  b=4;
  193.  fwrite(&b,sizeof(BYTE),1,ofile);
  194.  free(rol);
  195.  fclose(ofile);
  196. }
  197.  
  198. /* the compiler better not decide to rearrange these structures!!! */
  199. struct nameRecord
  200. {unsigned short index;
  201.  char used;
  202.  char name[9];
  203. };
  204.  
  205. #define GET(x) fread(&(ins->x),sizeof(ins->x),1,bFile)
  206.  
  207. void FMLoadInstrument(char *insName,char *bankFile,FMInstrument *ins)
  208. {FILE *bFile;
  209.  short int nmRecords,crap;
  210.  long int nameStart,dataStart;
  211.  struct nameRecord nr;
  212.  int i;
  213.  printf("Searching for %s...\n",insName);
  214.  bFile=fopen(bankFile,"rb");
  215.  if (!bFile)
  216.     {printf("Can't find bank file.\n");
  217.      exit(-1);
  218.     }
  219.  if (fseek(bFile,8,SEEK_SET))
  220.     {printf("Error reading bank file.\n");
  221.      exit(-1);
  222.     }
  223.  fread(&nmRecords,sizeof(nmRecords),1,bFile);
  224.  fread(&crap,sizeof(crap),1,bFile);
  225.  fread(&nameStart,sizeof(nameStart),1,bFile);
  226.  fread(&dataStart,sizeof(dataStart),1,bFile);
  227.  for (i=0;i<nmRecords;i++)
  228.     {fseek(bFile,nameStart+12*i,SEEK_SET);
  229.      fread(&nr,sizeof(nr),1,bFile);
  230.      if (nr.used && !stricmp(nr.name,insName))
  231.     break;
  232.     }
  233.  if (i==nmRecords)
  234.     {printf("Instrument: %s not found in bank file.\n",insName);
  235.      exit(-1);
  236.     }
  237.  fseek(bFile,dataStart+nr.index*30,SEEK_SET);
  238.  GET(MOD_waveForm); GET(MOD_waveForm);
  239.  GET(MOD_KSL); GET(MOD_fMult); GET(feedBack); GET(MOD_attack);
  240.  GET(MOD_sustain); GET(MOD_ss); GET(MOD_decay); GET(MOD_release);
  241.  GET(MOD_outputLevel); GET(MOD_amplitudeVibrato); GET(MOD_frequencyVibrato);
  242.  GET(MOD_envelopeScaling); GET(FM);
  243.  
  244.  GET(CAR_KSL); GET(CAR_fMult); GET(MOD_waveForm); GET(CAR_attack);
  245.  GET(CAR_sustain); GET(CAR_ss); GET(CAR_decay); GET(CAR_release);
  246.  GET(CAR_outputLevel); GET(CAR_amplitudeVibrato); GET(CAR_frequencyVibrato);
  247.  GET(CAR_envelopeScaling); GET(MOD_waveForm);
  248.  
  249.  GET(MOD_waveForm); GET(CAR_waveForm);
  250.  fclose(bFile);
  251. }
  252.  
  253.  
  254. int main(int argc,char **argv)
  255. {if (argc!=4)
  256.     {printf("Look, here's how it goes:\n");
  257.      printf("  %s <input file> <output_file> <bank_file>\n",argv[0]);
  258.      exit(-1);
  259.     }
  260.  translateROL(argv[1],argv[2],argv[3]);
  261.  printf("Okey dokey.\n");
  262.  return 0;
  263. }
  264.